package com.luzh.myspring.beans.factory;

import com.luzh.myspring.beans.BeanException;
import com.luzh.myspring.beans.PropertyValue;
import com.luzh.myspring.beans.PropertyValues;
import com.luzh.myspring.beans.factory.config.BeanDefinition;
import com.luzh.myspring.beans.factory.config.BeanFactoryPostProcessor;
import com.luzh.myspring.core.io.DefaultResourceLoader;
import com.luzh.myspring.core.io.Resource;
import com.luzh.myspring.util.StringValueResolver;

import java.io.IOException;
import java.util.Properties;

/**
 * 实例化之前的属性占位符解析器，需要手动配置
 */
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
    public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
    public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
    private String location="classpath:spring.properties";

    public void setLocation(String location) {
        this.location = location;
    }

    private static class PlaceholderResolvingStringValueResolver implements StringValueResolver {
        private final Properties properties;
        public PlaceholderResolvingStringValueResolver(Properties properties) {
            this.properties = properties;
        }

        /**
         * 占位符替换
         * @param strVal
         * @return
         */
        @Override
        public String resolveStringValue(String strVal) {
            StringBuilder buffer = new StringBuilder(strVal);
            int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
            int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
            if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) {
                String propKey = strVal.substring(startIdx + 2, stopIdx);
                String propVal = properties.getProperty(propKey);
                buffer.replace(startIdx, stopIdx + 1, propVal);
            }
            return buffer.toString();
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeanException {
        try {
            // 加载自定义属性文件
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());
            StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties);
            //修改xml中bean属性的占位符
            String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            for (String beanName : beanDefinitionNames) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) continue;//只解析字符串
                    String strVal = (String) value;
                    //???后来者替换
                    propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), valueResolver.resolveStringValue(strVal)));
                }
            }
            // 向容器中添加字符串解析器，供解析@Value注解使用
            beanFactory.addEmbeddedValueResolver(valueResolver);
        } catch (IOException e) {
            throw new BeanException("Could not load properties", e);
        }
    }

}

